package kn.pulldata.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class RedisLockService {

    @Autowired
    @Qualifier("redisTemplateDb2")
    private RedisTemplate<String, String> redisTemplate;

    public boolean tryLock(String key,String val){
        return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfPresent(key, val, 3, TimeUnit.DAYS));
    }
    public List<Boolean> obtainLocksInBatch(List<String> keys,long ttl) {
        List<Boolean> results = new ArrayList<>();
        String luaScript = "local results = {} " +
                "for i=1,#KEYS do " +
                "    local key = KEYS[i] " +
                "    local uuid = ARGV[1] " +
                "    local ttl = tonumber(ARGV[2]) " +
                "    if redis.call('EXISTS', key) == 0 then " +
                "        redis.call('SET', key, uuid, 'EX', ttl) " +
                "        table.insert(results, true) " +
                "    else " +
                "        table.insert(results, false) " +
                "    end " +
                "end " +
                "return results";

        String uuid = UUID.randomUUID().toString();
        // 创建字节数组列表并合并
        List<byte[]> keyBytes = new ArrayList<>();
        keyBytes.addAll(keys.stream()
                .map(key -> ("keywordMatch:Lock:" + key).getBytes()) // 添加前缀
                .collect(Collectors.toList()));        keyBytes.add(uuid.getBytes());
        keyBytes.add(String.valueOf(ttl).getBytes());

        // 将 List<byte[]> 转换为 byte[]...
        byte[][] keysAndArgs = keyBytes.toArray(new byte[0][]);

        List<Object> lockResults = redisTemplate.execute((RedisCallback<List<Object>>) connection ->
                connection.eval(
                luaScript.getBytes(StandardCharsets.UTF_8),
                ReturnType.MULTI,
                keys.size(),
                keysAndArgs
        ));

        if (lockResults != null) {
            for (Object result : lockResults) {
                if(Long.valueOf("1").equals(result)){
                    results.add(true);
                }else {
                    results.add(false);
                }
            }
        }
        return results;
    }
}
